#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
 
#include "idc_ubus_common.h"
#include "idc_ubus.h"
#include "idc_ubus_lora.h"
#include "idc_ubus_energy.h"

static const struct ubus_method idc_methods[] = {
        UBUS_METHOD("set_sleep", set_sleep, set_sleep_wake_policy),
        UBUS_METHOD("set_work", set_work, set_sleep_wake_policy),
        UBUS_METHOD("sync_timer", sync_timer, default_policy),
        UBUS_METHOD("set_addr", set_energy_id, entry_set_addr_policy),
        UBUS_METHOD("control_work", control_work, default_policy),
        UBUS_METHOD("control_sleep", control_sleep, default_policy),
        UBUS_METHOD("read_devs", read_devs, default_policy),
        UBUS_METHOD("reset_mt7621", reset_mt7621, default_policy),
        UBUS_METHOD("set_mt7621_run_mode", set_mt7621_run_mode, set_mt7621_run_mode_policy),
        UBUS_METHOD("query_timeinfo", query_timeinfo, default_policy),

        UBUS_METHOD("query_ver", query_lora_ver, default_policy),
        UBUS_METHOD("reboot", query_lora_reboot, default_policy),
        UBUS_METHOD("query_esn", query_lora_esn, default_policy),
        // UBUS_METHOD("in_at", lora_in_at, default_policy),
        // UBUS_METHOD("exit_at", lora_exit_at, default_policy),
        UBUS_METHOD("reset", lora_reset, default_policy),
        UBUS_METHOD("query_addr", query_lora_addr, default_policy),
        UBUS_METHOD("set_addr", set_lora_addr, lora_set_addr_policy),
        UBUS_METHOD("query_cell", query_lora_cell, default_policy),
        UBUS_METHOD("set_cell", set_lora_cell, lora_set_cell_policy),
        UBUS_METHOD("query_pwr", query_lora_pwr, default_policy),
        UBUS_METHOD("set_pwr", set_lora_pwr, lora_set_pwr_policy),
        //UBUS_METHOD("query_wor", query_lora_wor, default_policy),
        //UBUS_METHOD("set_wor", set_lora_wor, lora_set_wor_policy),
        UBUS_METHOD("query_bps", query_lora_bps, default_policy),
        UBUS_METHOD("set_bps", set_lora_bps, lora_set_bps_policy),
        UBUS_METHOD("query_lp", query_lora_lp, default_policy),
        UBUS_METHOD("set_lp", set_lora_lp, lora_set_lp_policy),
        //UBUS_METHOD("query_awake", query_lora_awake, default_policy),
        //UBUS_METHOD("set_awake", set_lora_awake, lora_set_awake_policy),
        UBUS_METHOD("query_trans", query_lora_trans, default_policy),
        UBUS_METHOD("set_trans", set_lora_trans, lora_set_trans_policy),
        //UBUS_METHOD("at_send", at_send_data, lora_set_trans_policy),
        //UBUS_METHOD("trans_send_data", at_send_data, lora_set_trans_policy),
};
const struct blobmsg_policy lora_addr_policy[] = {
        [0] = { .name = "addr", .type = BLOBMSG_TYPE_INT32 },
        [1] = { .name = "group_addr", .type = BLOBMSG_TYPE_INT32 },
        [2] = { .name = "is_center", .type = BLOBMSG_TYPE_INT32 },
};  
static struct ubus_object_type idc_object_type =  UBUS_OBJECT_TYPE("sihan.energy", idc_methods);
 
 
static struct ubus_object idc_object = {
        .name = "sihan.energy",
        .type = &idc_object_type,
        .methods = idc_methods,
        .n_methods = ARRAY_SIZE(idc_methods)
};
void get_lora_addr_callback(struct ubus_request *req, int type, struct blob_attr *msg) {
        if (!msg) {
                return;
        }
        struct blob_attr *tb[3];
        blobmsg_parse(lora_addr_policy, ARRAY_SIZE(lora_addr_policy), tb, blobmsg_data(msg), blobmsg_data_len(msg));
        if(tb[0]){
                runCfg.lora_addr = blobmsg_get_u32(tb[0]);
        }
        if(tb[1]){
                runCfg.lora_group = blobmsg_get_u32(tb[1]);
        }
        printf("lora_addr:%04X,lora_group:%04X\n", runCfg.lora_addr, runCfg.lora_group);
}
/**
 * 调用Energy服务,获取Lora地址信息
 */
int ubus_invoke_get_lora_addr() {
        struct ubus_context *ctx = ubus_connect(NULL);
        if (!ctx) {
                fprintf(stderr, "Failed to connect to ubus\n");
                return -1;
        }
    // 查找 network.device 的 ID
    uint32_t obj_id;
    if (ubus_lookup_id(ctx, "sihan.energy", &obj_id) != 0) {
        fprintf(stderr, "Failed to lookup sihan.energy\n");
        ubus_free(ctx);
        return -1;
    }

    blob_buf_init(&b, 0);
    
    // 发起异步调用
    int ret = ubus_invoke(ctx, obj_id, "query_addr", b.head, get_lora_addr_callback, 0, 3000);
    if (ret == 0) {}
    // 清理资源
    blob_buf_free(&b);
    ubus_free(ctx);
    return 0;
}
int ubus_doing()
{
        int ret;
 
        ctx = ubus_connect(NULL);
        if (!ctx) {
                fprintf(stderr, "Failed to connect to ubus\n");
                return -1;
        }
        ubus_add_uloop(ctx);
 
        ret = ubus_add_object(ctx, &idc_object);
        if (ret)
                fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret));
}
void *ubus_worker(void *arg)
{
        int ret;
        printf("idc_ubus_energy_init\n");
        uloop_init();
        ubus_doing();
        uloop_run();
 
        ubus_free(ctx);
        uloop_done();    
}
